/**
 * This file is released under the GNU General Public License.
 * Refer to the COPYING file distributed with this package.
 *
 * Copyright (c) 2008-2009 WURFL-Pro srl
 */
package net.sourceforge.wurfl.core.request;

import javax.servlet.http.HttpServletRequest;

import net.sourceforge.wurfl.core.request.normalizer.UserAgentNormalizer;
import net.sourceforge.wurfl.core.utils.UserAgentUtils;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * {@link WURFLRequestFactory} default implementation.
 * 
 * <p>
 * This is the implementation of {@link WURFLRequestFactory} building a
 * {@link DefaultWURFLRequest} implementation of WURFLRequest.
 * </p>
 * 
 * @author WURFL-PRO SRL, Rome, Italy
 * @version $Id: DefaultWURFLRequestFactory.java 1045 2009-03-09 15:52:53Z filippo.deluca $
 */
public class DefaultWURFLRequestFactory implements WURFLRequestFactory {

	/** Logger */
	private static final Log log = LogFactory.getLog(DefaultWURFLRequestFactory.class);

	/** User-Agent normalizer */
	private final UserAgentNormalizer userAgentNormalizer;

	/** User-Agent resolver */
	private final UserAgentResolver userAgentResolver;

	// Constructors *******************************************************

	/**
	 * Default constructor
	 * 
	 * <p>
	 * Create a {@link DefaultWURFLRequestFactory} using
	 * DefaultUserAgentResolver and UserAgentNormalizerChain.
	 * </p>
	 */
	public DefaultWURFLRequestFactory() {
		this(new DefaultUserAgentResolver(),
				new DefaultUserAgentNormalizerFactory().create());
	}

	/**
	 * Build {@link DefaultWURFLRequestFactory} by UserAgentNormalizer and
	 * UserAgentResolver.
	 * 
	 * @param userAgentResolver
	 *            The UserAgentResolver used to resolve user-agent.
	 * @param userAgentNormalizer
	 *            The UserAgentNormalizer used to normalize user-agents.
	 */
	public DefaultWURFLRequestFactory(UserAgentResolver userAgentResolver,
			UserAgentNormalizer userAgentNormalizer) {

		Validate.notNull(userAgentResolver, "userAgentResolver is null");
		Validate.notNull(userAgentResolver, "userAgentResolver is null");

		this.userAgentResolver = userAgentResolver;
		this.userAgentNormalizer = userAgentNormalizer;
	}

	/**
	 * Build {@link DefaultWURFLRequestFactory} by UserAgentNormalizer.
	 * 
	 * @param userAgentNormalizer
	 *            The UserAgentNormalizer used to normalize user-agents.
	 */
	public DefaultWURFLRequestFactory(UserAgentNormalizer userAgentNormalizer) {
		this(new DefaultUserAgentResolver(), userAgentNormalizer);
	}

	/**
	 * Build {@link DefaultWURFLRequestFactory} by UserAgentResolver.
	 * 
	 * @param userAgentResolver
	 *            The UserAgentResolver used to resolve user-agent.
	 */
	public DefaultWURFLRequestFactory(UserAgentResolver userAgentResolver) {
		this(userAgentResolver, new DefaultUserAgentNormalizerFactory()
				.create());
	}

	// Business methods ***************************************************

	/**
	 * Create a instance of {@link DefaultWURFLRequest} from an instance of
	 * {@link HttpServletRequest}.
	 * 
	 * <p>
	 * Uses UserAgentResolver to resolve request user-agent and
	 * UserAgentNormalizer to normalize resolved user-agent.
	 * </p>
	 * 
	 * @param sourceRequest
	 *            The HttpServletRequest from which build the WURFLRequest.
	 */
	public WURFLRequest createRequest(HttpServletRequest sourceRequest) {

		Validate.notNull(sourceRequest, "The sourceRequest must be not null");

		String userAgent = StringUtils.trimToEmpty(userAgentResolver
				.resolve(sourceRequest));

		if (StringUtils.isNotEmpty(userAgent)) {

			userAgent = userAgentNormalizer.normalize(userAgent);
		}

		String uaProf = UserAgentUtils.getUaProfile(sourceRequest);

		DefaultWURFLRequest request = new DefaultWURFLRequest(userAgent, uaProf);

		if (log.isDebugEnabled()) {
			log.debug("Created DefaultWURFLRequest: " + request);
		}

		return request;
	}

	/**
	 * Create a instance of {@link DefaultWURFLRequest} from an instance of
	 * {@link HttpServletRequest}.
	 * 
	 * <p>
	 * The given user-agent is normalized by UserAgentNormalizer.
	 * </p>
	 * 
	 * @param userAgent
	 *            The User-Agent from which build the WURFLRequest.
	 */
	public WURFLRequest createRequest(String userAgent) {

		userAgent = StringUtils.trimToEmpty(userAgent);

		// Normalizes user-agent
		if (StringUtils.isNotEmpty(userAgent)) {
			userAgent = userAgentNormalizer.normalize(userAgent);
		}

		return new DefaultWURFLRequest(userAgent, null);
	}

}
